package net.qiqbframework.eventhandling;


import lombok.Getter;
import net.qiqbframework.config.ConfigurationException;
import net.qiqbframework.common.transaction.NoTransactionManager;
import net.qiqbframework.common.transaction.TransactionManager;
import net.qiqbframework.messaging.SubscribableMessageSource;
import net.qiqbframework.messaging.monitoring.MessageMonitor;
import net.qiqbframework.messaging.task.RollbackConfiguration;
import net.qiqbframework.messaging.task.RollbackConfigurationType;

import javax.annotation.Nonnull;

import static net.qiqbframework.common.BuilderUtils.assertNonNull;

@Getter
public class SubscribingEventProcessorBuilder extends AbstractEventProcessorBuilder {

    private SubscribableMessageSource<EventMessage<?>> messageSource;
    private EventProcessingStrategy processingStrategy = DirectEventProcessingStrategy.INSTANCE;
    private TransactionManager transactionManager = NoTransactionManager.INSTANCE;

    public SubscribingEventProcessorBuilder() {
        super.rollbackConfiguration(RollbackConfigurationType.ANY_THROWABLE);
    }

    public static SubscribingEventProcessorBuilder getInstance() {
        return new SubscribingEventProcessorBuilder();
    }

    @Override
    public SubscribingEventProcessorBuilder name(@Nonnull String name) {
        super.name(name);
        return this;
    }

    @Override
    public SubscribingEventProcessorBuilder eventHandlerInvoker(@Nonnull EventMessageHandler eventHandlerInvoker) {
        super.eventHandlerInvoker(eventHandlerInvoker);
        return this;
    }

    @Override
    public SubscribingEventProcessorBuilder rollbackConfiguration(@Nonnull RollbackConfiguration rollbackConfiguration) {
        super.rollbackConfiguration(rollbackConfiguration);
        return this;
    }

    @Override
    public SubscribingEventProcessorBuilder errorHandler(@Nonnull ErrorHandler errorHandler) {
        super.errorHandler(errorHandler);
        return this;
    }

    @Override
    public SubscribingEventProcessorBuilder messageMonitor(@Nonnull MessageMonitor<? super EventMessage<?>> messageMonitor) {
        super.messageMonitor(messageMonitor);
        return this;
    }

    @Override
    public SubscribingEventProcessorBuilder spanFactory(@Nonnull EventProcessorSpanFactory spanFactory) {
        super.spanFactory(spanFactory);
        return this;
    }

    public SubscribingEventProcessorBuilder messageSource(@Nonnull SubscribableMessageSource<EventMessage<?>> messageSource) {
        assertNonNull(messageSource, "SubscribableMessageSource may not be null");
        this.messageSource = messageSource;
        return this;
    }

    public SubscribingEventProcessorBuilder processingStrategy(@Nonnull EventProcessingStrategy processingStrategy) {
        assertNonNull(processingStrategy, "EventProcessingStrategy may not be null");
        this.processingStrategy = processingStrategy;
        return this;
    }

    public SubscribingEventProcessorBuilder transactionManager(@Nonnull TransactionManager transactionManager) {
        assertNonNull(transactionManager, "TransactionManager may not be null");
        this.transactionManager = transactionManager;
        return this;
    }

    public SubscribingEventProcessor build() {
        return new SubscribingEventProcessor(this);
    }


    @Override
    protected void validate() throws ConfigurationException {
        super.validate();
        assertNonNull(messageSource, "The SubscribableMessageSource is a hard requirement and should be provided");
    }

}
